package com.atao.baokede.service.serviceImpl;

import com.atao.baokede.mapper.ReviewMapper;
import com.atao.baokede.pojo.Review;
import com.atao.baokede.service.ReviewService;
import com.atao.baokede.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReviewServiceImpl implements ReviewService {

    @Autowired
    private ReviewMapper reviewMapper;

    /**
     * 获取当前用户ID
     */
    private Long getCurrentUserId() {
        Map<String, Object> userMap = ThreadLocalUtil.get();
        return ((Number) userMap.get("id")).longValue();
    }

    @Override
    public void addMainReview(Review review) {
        // 设置评论级别为1（主评论）
        review.setLevel(1);
        review.setCreateTime(LocalDateTime.now());
        review.setUserId(getCurrentUserId());

        // 主评论必须有评分
        if (review.getScore() == null) {
            throw new IllegalArgumentException("主评论必须包含评分");
        }

        // 确保用户不能评论未购买的商品（这个检查需要订单服务支持）
        reviewMapper.insert(review);
    }

    @Override
    public void addReplyReview(Review review) {
        // 检查父评论是否存在
        Review parentReview = reviewMapper.findById(review.getParentId());
        if (parentReview == null) {
            throw new IllegalArgumentException("父评论不存在");
        }

        // 设置评论级别（二级或三级）
        review.setLevel(parentReview.getLevel() + 1);
        review.setCreateTime(LocalDateTime.now());
        review.setUserId(getCurrentUserId());
        review.setItemId(parentReview.getItemId());

        // 回复评论不需要评分
        review.setScore(null);

        reviewMapper.insert(review);
    }

    @Override
    public List<Review> getReviewsByItemId(Long itemId) {
        // 获取所有主评论
        List<Review> mainReviews = reviewMapper.findMainReviewsByItemId(itemId);

        // 为每个主评论加载其回复评论
        for (Review mainReview : mainReviews) {
            loadRepliesRecursively(mainReview);
        }

        return mainReviews;
    }

    /**
     * 递归加载评论的回复
     */
    private void loadRepliesRecursively(Review review) {
        List<Review> replies = reviewMapper.findRepliesByParentId(review.getId());
        // 为每个回复再加载其子回复
        for (Review reply : replies) {
            loadRepliesRecursively(reply);
        }
    }

    @Override
    public Review getReviewByUserIdAndItemId(Long itemId) {
        Long userId = getCurrentUserId();
        List<Review> reviews = reviewMapper.findByUserIdAndItemId(userId, itemId);
        return reviews.isEmpty() ? null : reviews.get(0);
    }

    @Override
    public List<Review> getRepliesByParentId(Long parentId) {
        return reviewMapper.findRepliesByParentId(parentId);
    }

    @Override
    public void deleteReview(Long id) {
        // 检查是否是当前用户的评论（可选的安全检查）
        Review review = reviewMapper.findById(id);
        if (review != null && review.getUserId().equals(getCurrentUserId())) {
            // 删除评论及其所有子评论
            // 这里简单实现，实际项目中可能需要更复杂的逻辑来处理多级评论的删除
            reviewMapper.deleteById(id);
        } else {
            throw new IllegalArgumentException("无法删除不属于当前用户的评论");
        }
    }

    @Override
    public void updateReview(Review review) {
        // 检查是否是当前用户的评论（可选的安全检查）
        Review existingReview = reviewMapper.findById(review.getId());
        if (existingReview != null && existingReview.getUserId().equals(getCurrentUserId())) {
            reviewMapper.update(review);
        } else {
            throw new IllegalArgumentException("无法更新不属于当前用户的评论");
        }
    }

    @Override
    public Double getAverageScoreByItemId(Long itemId) {
        return reviewMapper.getAverageScoreByItemId(itemId);
    }

    @Override
    public Map<Byte, Long> getScoreDistributionByItemId(Long itemId) {
        List<Map<String, Object>> scoreCounts = reviewMapper.getScoreDistributionByItemId(itemId);
        return scoreCounts.stream()
                .collect(Collectors.toMap(
                        // 将score从Object转换为Byte
                        entry -> ((Number) entry.get("score")).byteValue(),
                        // 将count从Object转换为Long
                        entry -> ((Number) entry.get("count")).longValue(),
                        (existing, replacement) -> existing,
                        LinkedHashMap::new
                ));
    }
}
